/*
 * @Author: 0x9DEFA478
 * @Date: 2024-07-31 16:38:22
 * @LastEditTime: 2024-09-16 16:15:32
 * @LastEditors: 0x9DEFA478
 * @Description: 
 * QQ:2652450237
 * ============================================================================================================================================
 * 
 * 
 * 
 *                                                                                               ************      ****************************
 *                                                                                             ************      ****************************  
 *                                                                                           ************      ****************************    
 *                                                                                         ************      ****************************      
 *                                                                                       ************      ************                        
 *                                                                                     ************      ************                          
 *                                                                                   ************      ************                            
 *                                                                                 ************      ************                              
 *                                                                               ************      ************                                
 *                                                                             ************      ************                                  
 *                                                                           ************      ************                                    
 *                                                                         ************      ************                                      
 *                                                                       ************      ************                                        
 *                                                                     ************      ************                                          
 *                                                                   ************      ************                                            
 *                                                                 ************      ************                                              
 *                                                               ************      ************                                                
 *                                                             ************      ************                                                  
 *                                                           ************      ************                                                    
 *                                                         ************      ************                                                      
 *                                                       ************      ************                                                        
 *                                                     ************      ************                                                          
 *                                                   ************      ************                                                            
 *                                                 ************      ************                                                              
 *                                               ************      ************                                                                
 *                                             ************      ************                                                                  
 *                                           ************      ************                                                                    
 *                                         ************      ************                                                                      
 *                                       ************      ************                                                                        
 *                                     ************      ************                                                                          
 *                                   ************      ************                                                                            
 *                                 ************      ************                                                                              
 *                               ************      ************                                                                                
 *                             ************      ************                                                                                  
 *                           ************      ************                                                                                    
 *                         ************      ************                                                                                      
 *       ****************************      ************                                                                                        
 *     ****************************      ************                                                                                          
 *   ****************************      ************                                                                                            
 * ****************************      ************                                                                                              
 * 
 * 
 * 
 * ============================================================================================================================================
 * 
 */
#include "./H_TS_Event.h"
#include "../LL/H_TS_LL.h"




int H_TS_Event_Triggering_ISR(H_TS_Event* Event){
  H_TS_Thread* Owner;

  Hsize Active;

  oH_TS_Assert_Core(H_TS_LL_Core_Instance.CurrentThread==NULL,"H_TS:H_TS_Event_Triggering_ISR():调度器未启动");
  oH_TS_Assert_HandleValid(Event==NULL,"H_TS:H_TS_Event_Triggering_ISR():空的句柄");

  if((Active=Event->Active)!=0){
    return Active;//此实现中 此时Active肯定为-1
  }
  Event->Active=-1;//激活事件

  //由于Active被设置 此时不会有更多的抢占中断到达这

  Owner=Event->Owner;
  if(Owner==NULL){
    //认为无线程正在等待信号
    return 0;
  }

  //有线程正在等待信号

  //优先级低的中断执行不到这里, 仅优先级最高的中断到达这里

  switch(Owner->Status){
    case vH_TS_Thread_Status_Block:

      Owner->Status=vH_TS_Thread_Status_Ready;//线程就绪
      Event->Owner=NULL;//清除占用标记 同时此标记让优先级低的中断不要进行后面的操作

      //让调度中断处理链表

      //添加到解阻塞链表
      H_TS_LL_AddThreadToBlock_IRQUnblockThreads(Owner);

      break;
    case vH_TS_Thread_Status_TimeBlock:

      Owner->Status=vH_TS_Thread_Status_Ready;//线程就绪
      Event->Owner=NULL;//清除占用标记 同时此标记让优先级低的中断不要进行后面的操作

      //让调度中断处理链表

      //添加到解阻塞(时间限制)链表
      H_TS_LL_AddThreadToTimeBlock_IRQUnblockThreads(Owner);

      break;
    default:
      oH_TS_Crash("H_TS:H_TS_Event_Triggering_ISR()出现严重错误\r\n");
      for(;;){
        //H_TS出BUG了!!!!!
      }
  }

  //触发调度中断
  oH_TS_LL_ISR_CallScheduleISR();
  return 0;
}

int H_TS_Event_Triggering(H_TS_Event* Event){
  H_TS_Thread* Owner;
  H_TS_Thread* p_last;
  H_TS_Thread* p_next;

  Hsize Active;
  Hsize Priority;
  int retVal;

  oH_TS_Assert_Core(H_TS_LL_Core_Instance.CurrentThread==NULL,"H_TS:H_TS_Event_Triggering():调度器未启动");
  oH_TS_Assert_HandleValid(Event==NULL,"H_TS:H_TS_Event_Triggering():空的句柄");

  //线程不像中断那样受到嵌套约束，线程可以从高优先级切换到低优先级
  //所以这里调度保护连Active一起保护
  //否则将可能发生：设置Active后，Owner判定前Active就被清零，并且在Active清零的情况下进行线程解阻塞操作，互斥保护失效
  oH_TS_LL_SchedulerSuspend();
  
  if((Active=Event->Active)!=0){
    oH_TS_LL_ResumeSchedulerAuto();
    return Active;//此实现中 此时Active肯定为-1
  }
  Event->Active=-1;//激活事件

  //由于Active被设置 此时不会有更多的抢占中断到达这
  //由于是线程执行该代码, 相关中断不会再访问后续代码涉及到的资源

  Owner=Event->Owner;
  if(Owner==NULL){
    //认为无线程正在等待信号
    oH_TS_LL_ResumeSchedulerAuto();
    return 0;
  }

  //有线程正在等待信号
  
  switch(Owner->Status){
    case vH_TS_Thread_Status_Block:

      Owner->Status=vH_TS_Thread_Status_Ready;//线程就绪
      Event->Owner=NULL;//清除占用标记

      //将线程从阻塞链表中移除
      p_last=Owner->List.Block.Last;
      p_next=Owner->List.Block.Next;
      if(p_last==NULL){
        H_TS_LL_Core_Instance.BlockThreads=p_next;
      }else{
        p_last->List.Block.Next=p_next;
      }
      if(p_next!=NULL){
        p_next->List.Block.Last=p_last;
      }

      goto lAddToReadyList;
    case vH_TS_Thread_Status_TimeBlock:

      Owner->Status=vH_TS_Thread_Status_Ready;//线程就绪
      Event->Owner=NULL;//清除占用标记

      //将线程从时间限制阻塞链表中移除
      p_last=Owner->List.TimeBlock.Last;
      p_next=Owner->List.TimeBlock.Next;
      if(p_last==NULL){
        H_TS_LL_Core_Instance.TimeBlockThreads=p_next;
      }else{
        p_last->List.TimeBlock.Next=p_next;
      }
      if(p_next!=NULL){
        p_next->List.TimeBlock.Last=p_last;
        p_next->BlockObject.TimeBlock.SleepTick+=Owner->BlockObject.TimeBlock.SleepTick;
      }

lAddToReadyList:
      H_TS_LL_ThreadAddToReadyList(Owner,p_next,Priority,retVal);
      oH_TS_LL_ResumeSchedulerCondition(retVal);
      break;
    default:
      oH_TS_Crash("H_TS:H_TS_Event_Triggering()出现严重错误\r\n");
      for(;;){
        //H_TS出BUG了!!!!!
      }
  }
  
  return 0;
}

int H_TS_Event_TryTake(H_TS_Event* Event){
  oH_TS_Assert_Core(H_TS_LL_Core_Instance.CurrentThread==NULL,"H_TS:H_TS_Event_TryTake():调度器未启动");
  oH_TS_Assert_HandleValid(Event==NULL,"H_TS:H_TS_Event_TryTake():空的句柄");
  if(Event->Active!=0){
    Event->Active=0;
    return 0;
  }
  return -1;
}

void H_TS_Event_Take(H_TS_Event* Event){
  H_TS_Thread* thisThread;
  H_TS_Thread* p_next;
  H_TS_Thread* p_last;

  oH_TS_Assert_Core(H_TS_LL_Core_Instance.CurrentThread==NULL,"H_TS:H_TS_Event_Take():调度器未启动");
  oH_TS_Assert_HandleValid(Event==NULL,"H_TS:H_TS_Event_Take():空的句柄");
  
  if(Event->Active!=0){
    Event->Active=0;
    return;
  }

  //无事件 开始阻塞

  thisThread=cH_TS_LL_ThisThread(H_TS_LL_Core_Instance);

  oH_TS_LL_SchedulerSuspend();

  thisThread->Status=vH_TS_Thread_Status_Block;

  //从就绪链表里移除
  H_TS_LL_ThreadRemoteThisFromReadyList(thisThread,p_next,p_last);

  //添加到阻塞链表
  H_TS_LL_ThreadAddToBlockList(thisThread,p_next);

  //标记事件句柄拥有线程
  Event->Owner=thisThread;

  if(Event->Active!=0){

    //由于Active被设置 此时不会有更多的抢占中断到达这
    //由于是线程执行该代码, 相关中断不会再访问后续代码涉及到的资源

    if(Event->Owner!=NULL){
      //在修改链表期间有事件触发 触发者不会进行链表修改工作
      
      thisThread->Status=vH_TS_Thread_Status_Ready;//线程就绪
      Event->Owner=NULL;//清除占用标记

      //让调度中断处理链表

      //添加到解阻塞链表
      H_TS_LL_AddThreadToBlock_IRQUnblockThreads(thisThread);

    }
  }

  oH_TS_LL_ResumeScheduler();//线程调度

  if(Event->Active==0){
    //H_TS出现BUG了 这是不应该出现的情况
    oH_TS_Crash("H_TS:H_TS_Event_Take()出现严重错误\r\n");
    for(;;){}
  }
  Event->Active=0;
  
}

int H_TS_Event_Take_Time(H_TS_Event* Event,H_TS_Tick Timeout){
  H_TS_Thread* thisThread;
  H_TS_Thread* p_next;
  H_TS_Thread* p_last;

  oH_TS_Assert_Core(H_TS_LL_Core_Instance.CurrentThread==NULL,"H_TS:H_TS_Event_Take_Time():调度器未启动");
  oH_TS_Assert_HandleValid(Event==NULL,"H_TS:H_TS_Event_Take_Time():空的句柄");
  
  if(Event->Active!=0){
    Event->Active=0;
    return 0;
  }

  if(Timeout<1){
    return -1;
  }

  //无事件 开始阻塞

  thisThread=cH_TS_LL_ThisThread(H_TS_LL_Core_Instance);

  oH_TS_LL_SchedulerSuspend();

  thisThread->Status=vH_TS_Thread_Status_TimeBlock;
  thisThread->BlockObject.TimeBlock.BlockObject=(void*)&Event->Owner;

  //从就绪链表里移除
  H_TS_LL_ThreadRemoteThisFromReadyList(thisThread,p_next,p_last);

  //添加到时间限制阻塞链表
  H_TS_LL_ThreadAddToTimeBlockList(thisThread,Timeout);

  //标记事件句柄拥有线程
  Event->Owner=thisThread;

  if(Event->Active!=0){

    //由于Active被设置 此时不会有更多的抢占中断到达这
    //由于是线程执行该代码, 相关中断不会再访问后续代码涉及到的资源

    if(Event->Owner!=NULL){
      //在修改链表期间有事件触发 触发者不会进行链表修改工作
      
      thisThread->Status=vH_TS_Thread_Status_Ready;//线程就绪
      Event->Owner=NULL;//清除占用标记

      //让调度中断处理链表

      //添加到解阻塞(时间限制)链表
      H_TS_LL_AddThreadToTimeBlock_IRQUnblockThreads(thisThread);

    }
  }

  oH_TS_LL_ResumeScheduler();//允许线程调度

  if(Event->Owner==0){
    //超时
    return -1;
  }
  Event->Owner=0;

  return 0;
}



